<?php
/*
 * "For me, it is far better to grasp the Universe 
 * 	as it really is
 * 	 than to persist in delusion,
 * 		 however satisfying and reassuring."
 * 		Carl Sagan
 * 
 * Description:
 * 		The Core::Registry class
 * 		For Registry classes to instantiate
 * 		use the UserRegistry.
 * 		
 * 
 */

class Core_Registry 
	implements Interface_Core_Registry{
	const VALUE_ERROR_TEMPLATE = 'Invalid object given';
	
	protected $_data;
	
	public function __construct( $object = null ){
		$this->overwrite( $object );
	}
	
	public function overwrite( $object ){
		if( $object === null )
			$this->_data = array();
		else if( is_string( $object ) and ($object instanceof ArrayAccess) )
			$this->_data = new $object;
		else if( is_array( $object ) or ($object instanceof ArrayAccess) )
			$this->_data = $object;
		else
			throw new Exception_Registry_ValueError( self::VALUE_ERROR_TEMPLATE );
	}
	
	public function read( $key = null ){
		if( $key === null )
			return $this->_data;
		
		if( is_array($key) ){
			$result = array();
			
			foreach( $key as $currKey => $currValue ){
				$result[$currKey] = $this->read( $currValue ); 	
			}
			
			return $result;
		}else{
			Core_Utility_ArrayKeys::assertIsValid( $key );
			return Core_Utility_ArrayAccess::read($this->_data, $key);
		}
	}
	
	public function safeRead( $key , $default = null ){
		try{	
			return $this->read( $key , $default );	
		}catch( Core_Exception_Generic_KeyError $e ){
			return $default;	
		}catch( Core_Exception_Generic_ValueError $e ){
			return $default;
		}
	}
	
	public function write( $key , $value = null , $object = null ){
		if( is_array( $key ) )
			foreach( $key as $currKey => $currValue )
				$this->write( $currKey , $currValue , $object );
		else{
			Core_Utility_ArrayKeys::assertIsValid( $key );
			return Core_Utility_ArrayAccess::write( $this->_data , $key , $value , $object );
		}
	}
	
	public function erase( $key , $check_first = false ){
		if( is_array($key) ){
			if( $check_first )
				foreach( $key as $currValue )
					if( !$this->has($currValue) )
						return;
			
			foreach( $key as $currValue )
				$this->erase( $currValue );
		}else{
			Core_Utility_ArrayKeys::assertIsValid( $key );
			return Core_Utility_ArrayAccess::erase( $this->_data , $key );
		}	
	}
	
	public function eraseExisting( $key ){
		if( is_array($key) )
			foreach( $key as $currValue )
				$this->eraseExisting( $currValue );
		else{
			try{	
				$this->erase( $key , false );	
			}catch( Exception_Registry_KeyError $e ){
				/// meh, ignore	
			}
		}
	}
	
	public function has( $key ){
		if( is_array( $key ) ){
			$result = array();
			
			foreach( $key as $currValue )
				$result[$currValue] = $this->has( $currValue );
			
			return $result;
		}
		
		Core_Utility_ArrayKeys::assertIsValid( $key );
		return Core_Utility_ArrayAccess::has( $this->_data , $key );
	}
}

